home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
DragClick
/
Sources
/
DragClick.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-21
|
5KB
|
264 lines
// =============================================================================
//
// InitUtils.cp
//
// Author: Greg Friedman
// Date: MacHack '96
//
// Do whatever you want with this source. Don't blame me if it doesn't work.
//
// =============================================================================
#ifndef __A4STUFF__
#include <A4Stuff.h>
#endif
#ifndef __DRAG__
#include <Drag.h>
#endif
#ifndef __DRAGCLICK__
#include "DragClick.h"
#endif
#ifndef __CONSTANTS__
#include "Constants.h"
#endif
#ifndef __GESTALTSTUFF__
#include "GestaltStuff.h"
#endif
#ifndef __INITUTILS__
#include "InitUtils.h"
#endif
#ifndef __LAYERMGR__
#include "LayerMgr.h"
#endif
static UniversalProcPtr gOldTEClick;
static OSType gDraggingProcess;
static void TEClickPatch();
static Boolean TEClickPatchHandler(Point thePt, Boolean extend, TEHandle hTE);
static void InstallTrackingPatchHandler();
static asm void DragDispatchPatch();
void main()
{
EnterCodeResource();
Handle showInitResource = Get1Resource('Code', 7000);
if (showInitResource)
((pascal void (*)(short, Boolean)) *showInitResource)(128, true);
OSErr err = DetachInitResource(kDragClickResType, kDragClickResID);
InitializeLists();
TEClickPatch();
DragDispatchPatch();
ExitCodeResource();
}
static asm void TEClickPatch()
{
move.w #_TEClick, d0
_GetToolTrapAddress
lea oldAddress, a1
move.l a0, (a1)
lea patchhead, a0
move.w #_TEClick, d0
_SetToolTrapAddress
rts
patchhead:
movem.l d0-d2/a0-a1, -(sp)
move.l 24(sp), -(sp) // push teHandle (5 saved regs + return addr)
move.b 32(sp), -(sp) // push extend
move.l 36(sp), -(sp) // push thePt
jsr TEClickPatchHandler // call c function
add.w #10, sp // pop params
tst.b d0
bne.s dontcalloriginal
movem.l (sp)+, d0-d2/a0-a1 // restore registers
move.l oldAddress, -(sp) // push old trap address
rts
dontcalloriginal:
movem.l (sp)+, d0-d2/a0-a1
move.l (sp),10(sp)
add.w #10, sp
rts
oldAddress:
dc.l 0 // storage for old address
}
static asm void DragDispatchPatch()
{
move.w #_DragDispatch, d0
_GetToolTrapAddress
lea oldAddress, a1
move.l a0, (a1)
lea patchhead, a0
move.w #_DragDispatch, d0
_SetToolTrapAddress
rts
patchhead:
cmp.w #1, d0 // test selector for InstallTrackingHandler
bne.s calloriginal
movem.l d0-d2/a0-a1, -(sp)
jsr InstallTrackingPatchHandler
movem.l (sp)+, d0-d2/a0-a1
calloriginal:
move.l oldAddress, -(sp)
rts
oldAddress:
dc.l 0
}
static Boolean TEClickPatchHandler(Point thePt, Boolean extend, TEHandle hTE)
{
EnterCodeResource();
Boolean result = FALSE;
if (!extend && HasProcessMgr())
{
OSType curSig;
long ticks = TickCount();
if (GetCurrentProcessSignature(&curSig) == noErr && (IsIncluded(curSig) || !IsExcluded(curSig)))
{
RgnHandle selectRgn = NewRgn();
if (selectRgn)
{
TEGetHiliteRgn(selectRgn, hTE);
Point globalPt = thePt;
LocalToGlobal(&globalPt);
if (PtInRgn(thePt, selectRgn) && WaitMouseMoved(globalPt))
{
gDraggingProcess = curSig;
DoDrag(thePt, selectRgn, hTE, ticks);
result = TRUE;
}
DisposeRgn(selectRgn);
}
}
}
ExitCodeResource();
return result;
}
void DoDrag(Point thePt, RgnHandle selectRgn, TEHandle hTE, long ticks)
{
RgnHandle tempRgn = NewRgn();
if (!tempRgn)
return;
InitCursor();
CopyRgn(selectRgn, tempRgn);
InsetRgn(tempRgn, 1, 1);
DiffRgn(selectRgn, tempRgn, selectRgn);
DisposeRgn(tempRgn);
// globalize the region
Point offsetPt = {0, 0};
LocalToGlobal(&offsetPt);
OffsetRgn(selectRgn, offsetPt.h, offsetPt.v);
OSErr err;
DragReference dragRef;
err = NewDrag(&dragRef);
if (err != noErr)
return;
Boolean wasLocked = FALSE;
if (!(HGetState((*hTE)->hText) & kMemLockMask))
{
HLock((*hTE)->hText);
wasLocked = TRUE;
}
err = AddDragItemFlavor(dragRef, 1, 'TEXT', &((*((*hTE)->hText))[(*hTE)->selStart]), (*hTE)->selEnd - (*hTE)->selStart, 0);
if (wasLocked)
HUnlock((*hTE)->hText);
Handle styleHandle = (Handle)TEGetStyleScrapHandle(hTE);
if (styleHandle)
{
HLock(styleHandle);
AddDragItemFlavor(dragRef, 1, 'styl', *styleHandle, GetHandleSize(styleHandle), 0);
DisposeHandle(styleHandle);
}
Rect itemBounds = (*selectRgn)->rgnBBox;
SetDragItemBounds(dragRef, 1, &itemBounds);
EventRecord event;
event.what = mouseDown; // mock-up an event record
event.message = 0;
event.when = ticks;
event.where = thePt;
event.modifiers = 0;
LocalToGlobal(&event.where);
//SetDragInputProc(dragRef, LocalDragInputProc, NULL);
TrackDrag(dragRef, &event, selectRgn);
DisposeDrag(dragRef);
}
void InstallTrackingPatchHandler()
{
EnterCodeResource();
OSType curSig;
if (GetCurrentProcessSignature(&curSig) == noErr)
{
if (!IsIncluded(curSig))
ExcludeCurrentProcess();
}
ExitCodeResource();
}
pascal OSErr LocalDragInputProc(Point* mouse,
short* modifiers,
void* /* dragInputRefCon */,
DragReference /* theDragRef */)
{
EnterCodeResource();
OSErr err = noErr;
if ((*modifiers & btnState) == 0 && (gDraggingProcess == kFinderCreator))
{
short windowPart;
WindowPtr foundWindow;
LayerPtr foundLayer = NULL;
windowPart = FindLayerWindow(*mouse, &foundWindow);
if (windowPart == 3)
err = -1;
else if (foundWindow)
{
foundLayer = WindowLayer(foundWindow);
if (((LayerPeek)foundLayer)->layerInfo->creator == kFinderCreator)
err = -1;
}
}
ExitCodeResource();
return err;
}